﻿using MyBookReadsList.Commands;
using MyBookReadsList.Data;
using MyBookReadsList.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Input;

namespace MyBookReadsList.ViewModels
{
    public class MyBooksViewModel : ViewModelBase, IPageViewModel, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private ICommand addNewCommand;
        private ICommand removeCommand;
        private ICommand editCommand;
        private ICommand selectionChange;
        private ICommand selectionBookChange;

        public ICommand SelectionBookChange
        {
            get
            {
                if (this.selectionBookChange == null)
                {
                    this.selectionBookChange = new RelayCommand(this.HandleSelectionBookChangeCommand);
                }
                return this.selectionBookChange;
            }
        }

        private void HandleSelectionBookChangeCommand(object parameter)
        {
            var args = parameter as SelectionChangedEventArgs;
            var selected = args.AddedItems;
            if (this.Books.Count() > 0)
            {
                this.ChangeBookSelection(selected[0]);
            }
        }

        public ICommand SelectionChange
        {
            get
            {
                if (this.selectionChange == null)
                {
                    this.selectionChange = new RelayCommand(this.HandleSelectionChangeCommand);
                }
                return this.selectionChange;
            }
        }

        private void HandleSelectionChangeCommand(object parameter)
        {
            var args = parameter as SelectionChangedEventArgs;
            var selected = args.AddedItems;
            if (this.Shelves.Count() > 0)
            {
                this.ChangeSelection(selected[0]);
            }
        }

        private ICommand removeBookCommand;

        public string Name
        {
            get 
            {
                return "My books"; 
            }
        }

        public ICommand Remove
        {
            get
            {
                if (this.removeCommand == null)
                {
                    this.removeCommand = new RelayCommand(this.HandleRemoveCommand);
                }
                return this.removeCommand;
            }
        }

        public ICommand RemoveBook
        {
            get
            {
                if (this.removeBookCommand == null)
                {
                    this.removeBookCommand = new RelayCommand(this.HandleRemoveBookCommand);
                }
                return this.removeBookCommand;
            }
        }

        private void HandleRemoveBookCommand(object parameter)
        {
            try
            {
                if (this.selectedBook == null)
                {
                    return;
                }
                DataPersister.RemoveBook(this.SelectedShelf, this.SelectedBook);
                this.Books = DataPersister.GetBooks(this.SelectedShelf);
                this.SelectedBook = null;
            }
            catch (Exception ex)
            {
                //this.SetErrorMessage(string.Format("Removing {0} failed with exception {1} ", this.NewStore.Name, ex.Message));
            }
        }



        public ICommand Edit
        {
            get
            {
                if (this.editCommand == null)
                {
                    this.editCommand = new RelayCommand(this.HandleEditCommand);
                }
                return this.editCommand;
            }
        }


        public ICommand AddNew
        {
            get
            {
                if (this.addNewCommand == null)
                {
                    this.addNewCommand = new RelayCommand(this.HandleAddNewCommand);
                }
                return this.addNewCommand;
            }
        }


        private void HandleRemoveCommand(object obj)
        {
            try
            {
                if (this.selectedShelf == null)
                {
                    return;
                }
                DataPersister.RemoveShelf(this.SelectedShelf);
                this.Shelves = DataPersister.GetShelves();
                this.SelectedShelf = null;
            }
            catch (Exception ex)
            {
                //this.SetErrorMessage(string.Format("Removing {0} failed with exception {1} ", this.NewStore.Name, ex.Message));
            }
        }


        private void HandleEditCommand(object obj)
        {
            try
            {
                if (this.selectedShelf == null)
                {
                    return;
                }
                DataPersister.SaveShelves(this.Shelves);
            }
            catch (Exception ex)
            {
            }
        }

        private Shelf newShelf;

        public Shelf NewShelf
        {
            get
            {
                return this.newShelf;
            }
            set
            {
                this.newShelf = value;
                this.OnPropertyChanged("NewShelf");
            }
        }

        private ObservableCollection<Shelf> shelves;
        private ObservableCollection<SimpleBook> books;

        private Shelf selectedShelf;
        private SimpleBook selectedBook;

        public Shelf SelectedShelf
        {
            get
            {
                return this.selectedShelf;
            }
            set
            {
                this.selectedShelf = value;
                OnPropertyChanged("SelectedShelf");
            }
        }

        public SimpleBook SelectedBook
        {
            get
            {
                return this.selectedBook;
            }
            set
            {
                this.selectedBook = value;
                OnPropertyChanged("SelectedBook");
            }
        }

        public IEnumerable<Shelf> Shelves
        {
            get
            {
                if (this.shelves == null)
                {
                    this.Shelves = DataPersister.GetShelves();
                }
                return this.shelves;
            }
            set
            {
                if (this.shelves == null)
                {
                    this.shelves = new ObservableCollection<Shelf>();
                }
                this.shelves.Clear();
                foreach (var item in value)
                {
                    this.shelves.Add(item);
                }
            }
        }


        public IEnumerable<SimpleBook> Books
        {
            get
            {
                if (this.books == null && this.SelectedShelf!=null)
                {
                    this.Books = DataPersister.GetBooks(this.SelectedShelf);
                }
                return this.books;
            }
            set
            {
                if (this.books == null)
                {
                    this.books = new ObservableCollection<SimpleBook>();
                }
                this.books.Clear();
                foreach (var item in value)
                {
                    this.books.Add(item);
                }
                OnPropertyChanged("Books");
            }
        }

        private void HandleAddNewCommand(object obj)
        {
            try
            {
                DataPersister.AddShelf(this.NewShelf);
                this.Shelves = DataPersister.GetShelves();
                this.NewShelf = new Shelf();
            }
            catch (Exception ex)
            {
                //this.SetErrorMessage(string.Format("Adding {0} failed with exception {1} ", this.NewStore.Name, ex.Message));
            }
        }

        protected void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public MyBooksViewModel()
        {
            this.NewShelf = new Shelf() { Title = "New shelf" };
            this.Books = new List<SimpleBook>() { new SimpleBook() { Title = "test" } };
        }

        public void ChangeSelection(object shelf)
        {
            this.SelectedShelf = shelf as Shelf;
            this.Books = DataPersister.GetBooks(this.SelectedShelf);
        }

        internal void ChangeBookSelection(object book)
        {
            this.SelectedBook = book as SimpleBook;
        }
    }
}
